package interfaces.hud.targetInfos;

import interfaces.superWidgets.ListenerKeeperElement;
import gameStates.absGamesStates.AbsIngameState;
import logic.common.player.Player;
import logic.common.player.playerListeners.PlayerTeamListener;
import logic.common.team.Team;
import logic.nodes.DestructionEvent;
import logic.nodes.DestructionListener;
import logic.nodes.TeamNode;
import logic.ships.hunter.Hunter;

import com.jme.renderer.Camera;
import com.jme.renderer.Renderer;
import com.jme.scene.Controller;
import com.jme.scene.Node;
import com.jme.scene.state.BlendState;
import com.jme.system.DisplaySystem;

public abstract class TargetInfoNode extends Node {
	
	private static final long serialVersionUID = 1L;
	
	protected Camera cam;
	protected TeamNode target;
	protected DisplaySystem display;
	protected boolean marked, isFriendly, neutral;
	protected PlayerTeamListener playerTeamListener;
	protected ListenerKeeperElement element;
	protected Player player;
	
	public TargetInfoNode(String name, TeamNode target, ListenerKeeperElement element) {
		super(name);
		this.target = target;
		this.element = element;
		assert(target != null);
		
		AbsIngameState ingameState = target.getIngameState();
		player = ingameState.getPlayer();
		
		neutral = target.getTeam() == null;
		isFriendly = target.getTeam() == player.getTeam();
		
		display = DisplaySystem.getDisplaySystem();
		cam = ingameState.getCam();
		
		BlendState bs = display.getRenderer().createBlendState();
		bs.setBlendEnabled(true);
		bs.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
		bs.setDestinationFunction(BlendState.DestinationFunction.OneMinusSourceAlpha);
		bs.setTestEnabled(true);
		bs.setTestFunction(BlendState.TestFunction.GreaterThan);
		setRenderState(bs);
		
		setRenderQueueMode(Renderer.QUEUE_ORTHO);
		setLightCombineMode(LightCombineMode.Off);
		updateRenderState();
				
		init();
		
		addController(new Controller() {
			private static final long serialVersionUID = 1L;
			@Override
			public void update(float time) {
				TargetInfoNode.this.update();
			}
		});
		
		addPlayerListener();
	}
	
	protected void addPlayerListener() {
		playerTeamListener = new PlayerTeamListener() {
			@Override
			public void teamChanged(Team newTeam) {
				TargetInfoNode.this.teamChanged();
			}
			
			@Override
			public void teamChangeFailed() {}
		};
		
		player.addPlayerTeamListener(playerTeamListener);
		
		if(!(target instanceof Hunter)) {
			target.addDestructionListener(new DestructionListener() {
				@Override
				public void destroyed(DestructionEvent event) {
					target.getIngameState().getPlayer().removePlayerTeamListener(playerTeamListener);
					removeFromParent();
				}
			});
		}
	}
	
	public void teamChanged() {
		isFriendly = target.getTeam() == target.getIngameState().getPlayer().getTeam();
	}
	
	protected abstract void init();
	
	public abstract void update();
	
	public void setMarked(boolean marked) {	this.marked = marked; }
}